# coding=utf-8

import os
import sys

reload(sys)
sys.setdefaultencoding("utf-8")

if not os.name == "nt":
    fp = open("pid.txt", "a")
    fp.write(str(os.getpid()) + "\n")
    fp.close()

if not os.name == "nt" and not os.name == "posix":
    from twisted.internet import epollreactor

    epollreactor.install()

if os.name == "nt":
    args = sys.argv
    if len(args) > 3 and args[3] == "iocp":
        from twisted.internet import iocpreactor as iocpreactor

        iocpreactor.install()

        x = sys.modules["twisted.internet.reactor"]
        print (x)

from firefly.netconnect.protoc import LiberateFactory
from twisted.web import vhost
from firefly.web.delayrequest import DelaySite
from firefly.distributed.root import PBRoot, BilateralFactory
from firefly.distributed.node import RemoteObject
from firefly.server.logobj import loogoo
from firefly.server.globalobject import GlobalObject
from twisted.python import log
from twisted.internet import reactor
from firefly.utils import services
import json


def serverStop():
    log.msg("stop")
    if GlobalObject().stophandler:
        GlobalObject().stophandler()
    reactor.callLater(0.5, reactor.stop)
    return True


class FFServer:
    def __init__(self):

        self.netfactory = None  # websocket
        self.root = None  #
        self.webroot = None  # http 服务
        self.remote = {}  # remote 节点
        self.master_remote = None
        self.db = None
        self.mem = None
        self.servername = None
        self.remoteportlist = []

    def config(self, config, servername=None, dbconfig=None, memconfig=None, masterconf=None):
        """
        配置服务器
        :param config:
        :param servername:
        :param dbconfig:
        :param memconfig:
        :param masterconf:
        :return:
        """
        '''配置服务器
            '''
        GlobalObject().json_config = config
        netport = config.get('netport')  # 客户端连接
        webport = config.get('webport')  # http连接
        rootport = config.get('rootport')  # root节点配置
        self.remoteportlist = config.get('remoteport', [])  # remote节点配置列表
        if not servername:
            servername = config.get('name')  # 服务器名称
        logpath = config.get('log')  # 日志
        hasdb = config.get('db')  # 数据库连接
        hasmem = config.get('mem')  # memcached连接
        app = config.get('app')  # 入口模块名称
        cpuid = config.get('cpu')  # 绑定cpu
        mreload = config.get('reload')  # 重新加载模块名称
        self.servername = servername

        if masterconf:
            masterport = masterconf.get('rootport')
            masterhost = masterconf.get('roothost')
            self.master_remote = RemoteObject(servername)
            addr = ('localhost', masterport) if not masterhost else (masterhost, masterport)
            self.master_remote.connect(addr)
            GlobalObject().masterremote = self.master_remote

        if netport:
            self.netfactory = LiberateFactory()
            netservice = services.CommandService("netservice")
            self.netfactory.addServiceChannel(netservice)
            reactor.listenTCP(netport, self.netfactory)

        if webport:
            self.webroot = vhost.NameVirtualHost()
            GlobalObject().webroot = self.webroot
            reactor.listenTCP(webport, DelaySite(self.webroot))

        if rootport:
            self.root = PBRoot()
            rootservice = services.Service("rootservice")
            self.root.addServiceChannel(rootservice)
            reactor.listenTCP(rootport, BilateralFactory(self.root))

        for cnf in self.remoteportlist:
            rname = cnf.get('rootname')
            self.remote[rname] = RemoteObject(self.servername)




        if logpath:
            log.addObserver(loogoo(logpath))  # 日志处理
        log.startLogging(sys.stdout)

        GlobalObject().config(netfactory=self.netfactory, root=self.root, remote=self.remote)
        if app:
            __import__(app)
        if mreload:
            _path_list = mreload.split(".")
            GlobalObject().reloadmodule = __import__(mreload, fromlist=_path_list[:1])
        GlobalObject().remote_connect = self.remote_connect
        if masterconf:
            masterport = masterconf.get('rootport')
            masterhost = masterconf.get('roothost')
            self.master_remote = RemoteObject(server_name)
            addr = ("localhost", masterport) if not masterhost else (masterhost, masterport)
            self.master_remote.connect(addr)
            GlobalObject().masterremote = self.master_remote

        # import firefly.server.admin


    def remote_connect(self, rname, rhost):
        """
        """
        for cnf in self.remoteportlist:
            _rname = cnf.get('rootname')
            if rname == _rname:
                rport = cnf.get('rootport')
                if not rhost:
                    addr = ('localhost', rport)
                else:
                    addr = (rhost, rport)
                self.remote[rname].connect(addr)
                break


    def start(self):

        log.msg("%s start...." % self.servername)
        log.msg("%s pid: %s " % (self.servername, os.getpid()))
        reactor.run()






if __name__ == "__main__":
    args = sys.argv
    server_name = None
    config = None
    if len(args) > 2:
        server_name = args[1]
        config = json.load(open(args[2], "r"))
    else:
        raise ValueError
    print "server_name =", server_name
    dbconf = config.get("db")
    memconf = config.get("memcached")
    sersconf = config.get("servers", {})
    masterconf = config.get("master", {})
    serconfig = sersconf.get(server_name)
    print "serconfig = ", serconfig
    ser = FFServer()
    ser.config(serconfig, servername=server_name, dbconfig=dbconf, memconfig=memconf, masterconf=masterconf)
    ser.start()

    if False:  # 这样可以保证模块在 pyinstaller 时被导入
        #
        pass
